use windows_sys::{
    Win32::Foundation::*, Win32::Graphics::Gdi::*, Win32::System::LibraryLoader::GetModuleHandleW,
    Win32::UI::Controls::*, Win32::UI::WindowsAndMessaging::*, core::*,
};

use std::ptr;
use windows_sys::core::PWSTR;

/// 将 Windows 宽字符串缓冲区转换为 Rust String
///
/// # 参数
/// - `buffer`: 包含宽字符串的缓冲区
/// - `len`: 实际字符数（不包括 null 终止符）
///
/// # 返回
/// 转换后的 Rust String
pub fn wide_to_string(buffer: &[u16], len: usize) -> String {
    if len == 0 {
        return String::new();
    }

    // 确保不越界
    let actual_len = len.min(buffer.len());
    String::from_utf16_lossy(&buffer[..actual_len])
}

/// 将 Windows 宽字符串缓冲区转换为 Rust String（自动检测长度）
///
/// # 参数
/// - `buffer`: 包含以 null 结尾的宽字符串的缓冲区
///
/// # 返回
/// 转换后的 Rust String
pub fn wide_to_string_auto(buffer: &[u16]) -> String {
    // 查找 null 终止符的位置
    if let Some(null_pos) = buffer.iter().position(|&c| c == 0) {
        String::from_utf16_lossy(&buffer[..null_pos])
    } else {
        // 如果没有找到 null，使用整个缓冲区
        String::from_utf16_lossy(buffer)
    }
}

/// 将 Rust 字符串转换为 Windows 宽字符串格式
///
/// # 参数
/// - `text`: Rust 字符串切片
///
/// # 返回
/// 包含 null 终止符的宽字符串 Vec<u16>
pub fn string_to_wide(text: &str) -> Vec<u16> {
    text.encode_utf16().chain(std::iter::once(0)).collect()
}

/// 将 Rust 字符串格式化为 Windows 宽字符串
///
/// # 参数
/// - `args`: 与 format! 宏相同的参数
///
/// # 返回
/// 包含 null 终止符的宽字符串 Vec<u16>
#[macro_export]
macro_rules! format_wide {
    ($($arg:tt)*) => {
        $crate::string_to_wide(&format!($($arg)*))
    };
}

/// 将 Windows 宽字符串指针转换为 Rust String
///
/// # 安全性
/// - 调用者必须确保 `wide_str` 指向有效的以 null 结尾的宽字符串
/// - 或者 `wide_str` 可以为 null，此时返回空字符串
///
/// # 参数
/// - `wide_str`: 指向以 null 结尾的宽字符串的指针
///
/// # 返回
/// 转换后的 Rust String，如果指针为 null 则返回空字符串
pub unsafe fn wide_ptr_to_string(wide_str: PWSTR) -> String {
    if wide_str.is_null() {
        return String::new();
    }

    // 计算以 null 结尾的字符串长度
    let mut len = 0;
    while *wide_str.offset(len) != 0 {
        len += 1;
    }

    // 创建切片并转换
    let slice = std::slice::from_raw_parts(wide_str, len as usize);
    String::from_utf16_lossy(slice)
}

/// 带长度限制的版本，防止读取过长的字符串
///
/// # 参数
/// - `wide_str`: 指向以 null 结尾的宽字符串的指针
/// - `max_len`: 最大允许读取的字符数（防止恶意或损坏的数据）
///
/// # 返回
/// 转换后的 Rust String
pub unsafe fn wide_ptr_to_string_limited(wide_str: PWSTR, max_len: usize) -> String {
    if wide_str.is_null() {
        return String::new();
    }

    // 计算以 null 结尾的字符串长度，但有最大限制
    let mut len = 0;
    while len < max_len && *wide_str.offset(len as isize) != 0 {
        len += 1;
    }

    // 创建切片并转换
    let slice = std::slice::from_raw_parts(wide_str, len);
    String::from_utf16_lossy(slice)
}
